package com.log.conn;

import com.log.administrator.LogManage;
import com.log.administrator.LogParamManage;
import com.log.unit.LogContext;
import com.log.utils.CommonUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.util.*;

/**
 * @ClassName LogAspect
 * @Author xiezhuocai
 * @Description TODO
 * @Date 2022/5/11 22:35
 */
@Aspect
public class LogAspect {

    private static final Logger log = LoggerFactory.getLogger(LogAspect.class);

    /**
     * 切入点
     */
    @Pointcut("@annotation(com.log.conn.SysLogParam)")
    public void crmAspect() {
    }

    @Around("@annotation(sysLogParam)")
    public Object saveSysLog(ProceedingJoinPoint joinPoint, SysLogParam sysLogParam) throws Throwable {
        LogManage manage = new LogParamManage(sysLogParam.value(),sysLogParam.stock(),sysLogParam.mSpEL(),sysLogParam.fun());
        LogContext logContext = manage.getLogContext();
        Object result =null;
        //判断是否需要解析
        if(logContext.isSection()){
            LogContext.Resolver.putEmptySpan();
            setResolverValue(sysLogParam);
            try {
                Map<String,String> logBodyMap = new HashMap<>();
                if(logContext.isStock()){
                    LogContext.Resolver.putVariable("stockAnalysisValue", logContext.getStockKey());
                    logBodyMap.putAll(CommonUtils.consanguinity(logContext.getBodyKey(),logContext.getStockKey()));
                }
                if (logContext.isMSpEL()) {
                    MethodSignature signature = (MethodSignature) joinPoint.getSignature();
                    //获取执行的代理对象
                    Object runAgency = joinPoint.getThis();
                    Map<String, String> mSpELAnalysisValue = manage.spELFun(logContext.getmSpELKey(), runAgency,
                            signature.getMethod(), joinPoint.getArgs());
                    LogContext.Resolver.putVariable("mSpELAnalysisValue", mSpELAnalysisValue);
                    logBodyMap.putAll(CommonUtils.consanguinity(logContext.getBodyKey(),mSpELAnalysisValue));
                }
                if (logContext.isFun()&&logContext.getFunChain()!=null){
                    Map<String,String> funAnalysisValue = new HashMap<>();
                    logContext.getFunChain().handlerRequest(logContext.getFunKey(), funAnalysisValue);
                    LogContext.Resolver.putVariable("funAnalysisValue", funAnalysisValue);
                    logBodyMap.putAll(CommonUtils.consanguinity(logContext.getBodyKey(),funAnalysisValue));
                }

                result = run(joinPoint);

                log.info(manage.getLogBody().entirely(logBodyMap));

            } finally {
                LogContext.Resolver.clear();
            }
        } else {
            result = run(joinPoint);
            log.info(logContext.getBodyValue());
        }
        return result;
    }

    public void setResolverValue(SysLogParam sysLogParam){
        LogContext.Resolver.putVariable("SysLogParam.value", sysLogParam.value());
        LogContext.Resolver.putVariable("SysLogParam.stock", sysLogParam.stock());
        LogContext.Resolver.putVariable("SysLogParam.fun", sysLogParam.fun());
        LogContext.Resolver.putVariable("SysLogParam.mSpEL", sysLogParam.mSpEL());
    }

    public Object run(ProceedingJoinPoint joinPoint){
        try {
            return joinPoint.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            log.error("异常:{}",throwable.getMessage());;
            return null;
        }
    }

    //方类名称
    public String className(ProceedingJoinPoint point){
        return point.getTarget().getClass().getName();
    }

    //方法名称
    public String methodName(Method method){
        return method.getName();
    }
}
